﻿using MyAlbum.Services;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System;
using System.Linq;
using MyAlbum.Model;
using PersonalAlbum.Exceptions;
namespace UnitTests
{
    
    
    /// <summary>
    ///This is a test class for SupportServiceTest and is intended
    ///to contain all SupportServiceTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SupportServiceTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {

        }
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            _testConfig = new TestConfig();
            supports = new List<MyAlbum.Model.Support>();
        }
        //
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            foreach (var item in supports)
            {
                Service.DeleteItem(item);
            }
            _testConfig.Dispose();
        }
        //
        #endregion
        private TestConfig _testConfig;
        private List<MyAlbum.Model.Support> supports;
        MyAlbum.Services.SupportService Service
        {
            get
            {
                return ObjectFactory.GetInstance<IDataService<Support>>() as MyAlbum.Services.SupportService;
            }
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);
            item.Body = Guid.NewGuid().ToString();
            item.Name = Guid.NewGuid().ToString();
            item.Subject = Guid.NewGuid().ToString();
            item.Email = Guid.NewGuid().ToString();
            item.IsActive = false;
            target.UpdateItem(item, new MyAlbum.Utility.GenericValidationSummary());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest_Null_Body()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);
            item.Body = null;
            target.UpdateItem(item, new MyAlbum.Utility.GenericValidationSummary());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Body == string.Empty)//it comes as empty string and not null
            {
                loaded.Body = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest_Null_Email()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);
            item.Email = null;
            target.UpdateItem(item, new MyAlbum.Utility.GenericValidationSummary());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Email == string.Empty)//it comes as empty string and not null
            {
                loaded.Email = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest_Null_Name()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);
            item.Name = null;
            target.UpdateItem(item, new MyAlbum.Utility.GenericValidationSummary());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Name == string.Empty)//it comes as empty string and not null
            {
                loaded.Name = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest_Null_Subject()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            item.Subject = null;
            target.UpdateItem(item, new MyAlbum.Utility.GenericValidationSummary());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Subject == string.Empty)//it comes as empty string and not null
            {
                loaded.Subject = null;
            }
            Compare(item, loaded);
        }


        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void UpdateItem_Null_Item()
        {
            MyAlbum.Services.SupportService target = this.Service;
            target.UpdateItem(null, new MyAlbum.Utility.GenericValidationSummary());

        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItems().SingleOrDefault(s => s.Id == item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetItemByIdTest()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for DeleteItem
        ///</summary>
        [TestMethod()]
        public void DeleteItemTest()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            MyAlbum.Model.Support item2 = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item2, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item2);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
            target.DeleteItem(item);

            loaded = target.GetItemById(item.Id);
            Assert.IsNull(loaded);

            //and check that the other one is not deleted
            Assert.IsNotNull(target.GetItemById(item2.Id));

        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest_Null_Body()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
               
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Body == string.Empty)//it comes as empty string and not null
            {
                loaded.Body = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest_Null_Email()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
              
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Email == string.Empty)//it comes as empty string and not null
            {
                loaded.Email = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest_Null_Name()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
              
                Subject = Guid.NewGuid().ToString(),
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Name == string.Empty)//it comes as empty string and not null
            {
                loaded.Name = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest_Null_Subject()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                
                IsActive = true,
                TimeStamp = DateTime.Now
            };
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(item, v);
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            if (loaded.Subject == string.Empty)//it comes as empty string and not null
            {
                loaded.Subject = null;
            }
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest_Null_Date()
        {
            MyAlbum.Services.SupportService target = this.Service;
            MyAlbum.Model.Support item = new Support()
            {
                Body = Guid.NewGuid().ToString(),
                Email = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Subject = Guid.NewGuid().ToString(),
                IsActive = true                
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.supports.Add(item);

            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItem_Null_Item()
        {
            MyAlbum.Services.SupportService target = this.Service;
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(null, v);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("item", v.Errors.Keys.First());
           
        }

        private void Compare(Support expected, Support actual)
        {
            Assert.AreEqual(expected.Body ?? string.Empty, actual.Body ?? string.Empty);
            Assert.AreEqual(expected.Email ?? string.Empty, actual.Email ?? string.Empty);
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.IsActive, actual.IsActive);
            Assert.AreEqual(expected.Name ?? string.Empty, actual.Name ?? string.Empty);
            Assert.AreEqual(expected.Subject ?? string.Empty, actual.Subject ?? string.Empty);
            if (TestConfig._mode == PersistenceModes.Xml)
            {
                Assert.AreEqual(expected.TimeStamp, actual.TimeStamp);
            }
        }

        /// <summary>
        ///A test for SupportService Constructor
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void SupportServiceConstructorTest()
        {
            MyAlbum.Data.IRepository<MyAlbum.Model.Support> supportRepository = null; 
            MyAlbum.Services.SupportService target = new MyAlbum.Services.SupportService(supportRepository,null,null);
        }
    }
}
